package com.diy.sigmund.diyorder.test.controller;

import com.diy.sigmund.diycommon.entity.ResultMsg;
import com.diy.sigmund.diycommon.entity.po.user.UserAuth;
import com.diy.sigmund.diycommon.spring.CustomApplicationContext;
import com.diy.sigmund.diycommon.spring.anno.IgnoreTokenVerification;
import com.diy.sigmund.diycommon.spring.config.util.RestTemplateUtil;
import com.diy.sigmund.diyorder.entity.dto.UserAuthDTO;
import com.diy.sigmund.diyorder.feign.client.UserClient;
import com.yomahub.tlog.core.annotation.TLogAspect;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author ylm-sigmund
 * @since 2021/4/18 15:44
 */
@RestController
@RequestMapping("/order/feignTest")
public class FeignTestController {

    @Autowired
    private UserClient userClient;
    @Autowired
    private RestTemplateUtil restTemplateUtil;

    private static final Logger log = LoggerFactory.getLogger(FeignTestController.class);

    @IgnoreTokenVerification
    @PostMapping("/commonTest")
    @TLogAspect({"dto.identifier", "dto.credential"})
    public ResultMsg commonTest(@RequestBody UserAuthDTO dto) throws Exception {
        log.info("微服务调用测试开始");
        dto.setIdentifier("18727613670");
        dto.setCredential("123456");
        dto.setIdentityType("1");
        dto.setIsExternalLogin("0");
        // 异步
        CustomApplicationContext.getBean(FeignTestController.class).testPrint(null);
        CustomApplicationContext.getBean(FeignTestController.class).testFuture(null);
        // http
        handleRestTemplate(dto);
        // feign
        ResultMsg login = getFeignResult(dto);
        // mq
        // CustomApplicationContext.getBean(MqTestController.class).sendBoot();
        // CustomApplicationContext.getBean(MqTestController.class).sendMessageInTransaction("onlyTest");
        log.info("所有的调用都完成");
        return login;
    }

    /**
     * // {
     * //     "identityType":"1",
     * //         "isExternalLogin":"0",
     * //         "identifier":"18727613670",
     * //         "credential":"123456"
     * // }
     */
    @IgnoreTokenVerification
    @PostMapping("/testLogin")
    @TLogAspect({"dto.identifier", "dto.credential"})
    public ResultMsg login(@RequestBody UserAuthDTO dto) {
        //  1、配置MDC导致日志文件相关内容缺失、且存在报错--未发现
        //  不支持zuul网关-【gitee】铂赛东：2022-03-23 暂且还没支持，会加入计划
        // todo tlog 遗留问题：
        //  19:39:45,667 |-ERROR in com.yomahub.tlog.core.enhance.logback.async.AspectLogbackAsyncAppender[SYSTEM_FILE_ASYNC] - Appender [SYSTEM_FILE_ASYNC] failed to append. java.lang.IllegalStateException: The MDCPropertyMap has been already set for this event.
        //  ELK收集的日志打印2遍日志追踪内容:[NONE][NONE][0][11120381046603840] [NONE][NONE][0][11120381046603840],控制台和日志文件均正常
        //  oauth2服务未打印追踪日志[NONE][NONE][0][11120381046603840]

        dto.setIdentifier("18727613670");
        dto.setCredential("123456");
        // 已生效：异步线程支持
        // CustomApplicationContext.getBean(FeignTestController.class).testPrint(null);
        // 对于mq中间件的支持 rocketMq看起来不太行
        // 已生效：任务框架的支持 从1.3.0版本开始，TLog对开源框架XXL-JOB做了支持。无需任何改动，只需引入依赖包即可

        // 已生效：对RestTemplate的支持
        // handleRestTemplate(dto);
        // 已生效：feign调用，但是a只传递到b，没有传递到c
        ResultMsg login = getFeignResult(dto);
        log.info("所有的调用都完成");
        return login;
    }

    private void handleRestTemplate(UserAuthDTO dto) {
        // 请求头信息
        HttpHeaders headers = new HttpHeaders();
        // 组装请求信息
        HttpEntity<Object> httpEntity = new HttpEntity<>(dto, headers);
        restTemplateUtil.postForObject("http://localhost:8002/user/userAuth/login", httpEntity, Object.class);
    }

    private ResultMsg getFeignResult(UserAuthDTO dto) {
        return userClient.login(dto);
    }

    @Async("customAsyncExecutor")
    public void testPrint(UserAuth userAuth) {
        log.info("这是测试ThreadPoolConfiguration");
        log.info("这是测试ThreadPoolTaskExecutor");
        log.info("这是测试@Configuration");
        log.info("这是测试异步线程池名称");
        log.info("这是测试 tLog");
    }

    @Async("customAsyncExecutor")
    public Future<ResultMsg> testFuture(UserAuth userAuth) throws Exception {
        log.info("这是测试ThreadPoolConfiguration");
        log.info("这是测试ThreadPoolTaskExecutor");
        log.info("这是测试@Configuration");
        log.info("这是测试异步线程池名称");
        TimeUnit.SECONDS.sleep(2);
        return new AsyncResult<>(ResultMsg.success(userAuth));
    }
}
